import { DemoGrid } from 'components/Demo/DemoGrid'
import { Demo } from 'components/Demo/Demo'

import ParallaxVert from '@react-spring/demo/src/sandboxes/parallax-vert/src/App'
import Parallax from '@react-spring/demo/src/sandboxes/parallax/src/App'
import ParallaxSticky from '@react-spring/demo/src/sandboxes/parallax-sticky/src/App'

# Parallax

## Overview

```js
import { Parallax, ParallaxLayer } from '@react-spring/parallax'
```

`Parallax` creates a scrollable container. `ParallaxLayer`s contain your content and will be moved according to their offsets and speeds.

**NOTE**: Currently, only `@react-spring/web` is supported.

```jsx render=true edit=true
<Parallax pages={2} style={{ top: '0', left: '0' }}>
  <ParallaxLayer
    offset={0}
    speed={2.5}
    style={{ display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
    <p>Scroll down</p>
  </ParallaxLayer>

  <ParallaxLayer offset={1} speed={2} style={{ backgroundColor: '#ff6d6d' }} />

  <ParallaxLayer
    offset={1}
    speed={0.5}
    style={{
      display: 'flex',
      justifyContent: 'center',
      alignItems: 'center',
      color: 'white',
    }}>
    <p>Scroll up</p>
  </ParallaxLayer>
</Parallax>
```

## Parallax

| Property    | Type          | Description                                                                      |
| ----------- | ------------- | -------------------------------------------------------------------------------- |
| pages       | number        | Total space of the container. Each page takes up 100% of the viewport.           |
| config?     | SpringConfig  | The spring behavior. Defaults to `config.slow` (see [configs](/common/configs)). |
| enabled?    | boolean       | Whether or not the content can be scrolled. Defaults to `true`.                  |
| horizontal? | boolean       | Whether or not the container scrolls horizontally. Defaults to `false`.          |
| innerStyle? | CSSProperties | CSS object to style the inner `Parallax` wrapper (not the scrollable container)  |

### `scrollTo`

`Parallax` also has a `scrollTo` function for click-to-scroll. It takes one paramater: the number of the page to scroll to
(Pages are zero-indexed so `scrollTo(0)` will scroll to the first page, etc).

### Usage Notes

- All direct `children` of `Parallax` must be `ParallaxLayer`s (or `fragment`s whose only direct `children` are `ParallaxLayer`s).
- `Parallax` is a scrollable container so all scroll events are fired from the container itself -- listening for scroll on `window` won't work.
- `scrollTo` is a method on `Parallax` -- you access it with a `ref` and then `ref.current.scrollTo(pageNumber)`.

## ParallaxLayer

| Property    | Type         | Description                                                                                                                                        |
| ----------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| factor?     | number       | Size of the layer relative to page size (eg: `1` => 100%, `1.5` => 150%, etc). Defaults to `1`.                                                    |
| offset?     | number       | The offset of the layer when it's corresponding page is fully in view (eg: `0` => top of 1st page, `1` => top of 2nd page, etc ). Defaults to `0`. |
| speed?      | number       | Rate at which the layer moves in relation to scroll. Can be positive or negative. Defaults to `0`.                                                 |
| horizontal? | boolean      | Whether or not the layer moves horizontally. Defaults to the `horizontal` value of `Parallax` (whose default is `false`).                          |
| sticky?     | StickyConfig | If set, the layer will be 'sticky' between the two offsets. All other props are ignored. Default: `{start?: number = 0, end?: number = start + 1}` |

### Usage Notes

- The `offset` prop is where the layer will end up, not where it begins. For example, if a layer has an offset of `1.5`, it will be halfway down the second page (zero-indexed) when the second page completely fills the viewport.
- The `speed` prop will affect the initial starting position of a layer, but not it's final `offset` position.
- Any layer with `sticky` set will have a `z-index` higher than regular layers. This can be changed manually.

## Demos

<DemoGrid>
  <Demo title="Parallax">
    <Parallax />
  </Demo>
  <Demo title="Parallax Vert">
    <ParallaxVert />
  </Demo>
  <Demo title="Parallax Sticky">
    <ParallaxSticky />
  </Demo>
</DemoGrid>
